//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
#include <windows.h>
#include <iplcommon.h>
#include <fmd.h>
#include <bootpart.h>
#include <oal.h>
#include <boot.h>
#include <bsp.h>


//------------------------------------------------------------------------------
//  IMGFS_BOOT_SECTOR structure must be kept in sync with the one in
//  %_WINCEROOT%\public\common\oak\drivers\ethdbg\fallite\bphelp.cpp
//------------------------------------------------------------------------------
typedef struct
{
    GUID guidReserved;
    DWORD dwReserved1;
    DWORD dwReserved2;
    DWORD dwReserved3;
    DWORD dwReserved4;
    DWORD dwReserved5;
    DWORD dwReserved6;
    DWORD dwReserved7;
    DWORD dwReserved8;
    DWORD dwReserved9;
    DWORD dwReserved10;
    DWORD dwUpdateModeFlag;
} IMGFS_BOOT_SECTOR;

//------------------------------------------------------------------------------
//
//  Global variables
//
//  This variables are used by IPLCommon when other functions in this
//  wrapper are called. As we will ignore them in our wrapper functions
//  they can be set to any value.
//
extern UINT32 g_ulFlashBase       ;
extern UINT32 g_ulFlashLengthBytes;
extern UINT32 g_ulBPartBase       ;
extern UINT32 g_ulBPartLengthBytes;

//------------------------------------------------------------------------------
//
//  Function: BP_Init
//
//  This function should open boot storage. We will simply fill configuration
//  and call BootStoreInit function.
//
BOOL
BP_Init(
    LPBYTE pMemory,
    DWORD dwSize,
    LPCTSTR lpActiveReg,
    PPCI_REG_INFO pRegIn,
    PPCI_REG_INFO pRegOut
    )
{
    // FMD_Init will be called through BP_OpenPartition (BootStoreGetHandle)
    return TRUE;
}

//------------------------------------------------------------------------------

HANDLE
BP_OpenPartition(
    DWORD dwStartSector,
    DWORD dwNumSectors,
    DWORD dwPartType,
    BOOL fActive,
    DWORD dwCreationFlags
    )
{
    HANDLE hStore;

    // Get store handle
    hStore = BootStoreGetHandle(0);
    if (hStore == NULL)
        {
        hStore = INVALID_HANDLE_VALUE;
        goto cleanUp;
        }

    // We only know how to open partition, not create one
    if (dwCreationFlags != PART_OPEN_EXISTING) goto cleanUp;

    // Try open partition
    if (!BootStoreOpenPartition(
            hStore, BOOT_STORE_ACCESS_READ, dwPartType, 0
            ))
        {
        hStore = INVALID_HANDLE_VALUE;
        goto cleanUp;
        }

cleanUp:    
    return hStore;
}

//------------------------------------------------------------------------------

BOOL
BP_SetDataPointer(
    HANDLE hPartition,
    DWORD dwAddress
    )
{
    return BootStoreSeek(hPartition, dwAddress);
}

//------------------------------------------------------------------------------

BOOL
BP_ReadData(
    HANDLE hPartition,
    LPBYTE pbBuffer,
    DWORD dwLength
    )
{
    BOOL rc = FALSE;
    UINT32 count;
    
    // Read data
    count = BootStoreRead(hPartition, pbBuffer, dwLength);
    rc = (count == dwLength);
    return rc;
}

//------------------------------------------------------------------------------

BOOL
BP_GetUpdateModeFlag(
    BOOL *pUpdateMode
    )
{
    BOOL rc = FALSE;
    HANDLE hStore = NULL;
    IMGFS_BOOT_SECTOR imgfsBootSector; 

    // Check parameter
    if (pUpdateMode == NULL) goto cleanUp;

    // Get store handle
    hStore = BootStoreGetHandle(0);
    if (hStore == NULL) goto cleanUp;

    // Open
    if (!BootStoreOpenPartition(hStore, BOOT_STORE_ACCESS_READ, PART_IMGFS, 0)) {
        OALMSG(OAL_ERROR, (L"ERROR: Failed to open IMGFS partition\r\n"));
        goto cleanUp;
        }

    // Seek to position logical sector 0 in the filesystem
    if (!BootStoreSeek(hStore, 0)) {
        OALMSG(OAL_ERROR, (L"ERROR: Could not seek to logical sector 0\r\n"));
        goto cleanUp;    
        }

    // Read flag
    if (BootStoreRead(hStore, &imgfsBootSector, sizeof(imgfsBootSector)) != sizeof(imgfsBootSector)) {
        OALMSG(OAL_ERROR, (L"ERROR: Failed to read from IMGFS partition\r\n"));
        goto cleanUp;
        }

    // We are done
    *pUpdateMode = imgfsBootSector.dwUpdateModeFlag;
    rc = TRUE;

cleanUp:
    if (hStore != NULL) BootStoreClose(hStore);
    return rc;    
}

//------------------------------------------------------------------------------

BOOL
FAL_LockFlashRegion(
    REGION_TYPE regionType
    )
{
    return FALSE;
}

//------------------------------------------------------------------------------

BOOL
FAL_UnlockFlashRegion(
    REGION_TYPE regionType
    )
{
    return FALSE;
}

//------------------------------------------------------------------------------
